package com.ae.shield.common.gui.container;

import com.ae.shield.common.block.BlockList;
import com.ae.shield.common.block.tile.NanoRobotProgrammerTile;
import com.ae.shield.common.items.EffectStorageItem;
import com.ae.shield.common.items.NanoTool;
import com.ae.shield.common.items.shieldFittings.makers.NanoRobot;
import com.ae.shield.common.items.shieldFittings.makers.ShieldMakerBase;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.IWorldPosCallable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.SlotItemHandler;

import javax.annotation.Nonnull;

public class NanoRobotProgrammerContainer extends Container {
    private final IWorldPosCallable callable;
    private final NanoRobotProgrammerTile blockTile;
    private final PlayerInventory playerInv;

    public NanoRobotProgrammerContainer(int id, @Nonnull PlayerInventory playerInventory, BlockPos pos) {
        super(ContainerList.NANO_ROBOT_PROGRAMMER_CONTAINER.get(), id);
        World world = playerInventory.player.world;
        callable = IWorldPosCallable.of(world, pos);
        blockTile = (NanoRobotProgrammerTile) world.getTileEntity(pos);
        playerInv = playerInventory;
        loadSlot();
    }

    public NanoRobotProgrammerContainer(int id, PlayerInventory playerInventory, PacketBuffer buffer) {
        this(id, playerInventory, buffer.readBlockPos());
    }

    private void loadSlot() {
        //创建玩家背包
        for (int row = 0; row < 3; row++) {
            for (int column = 0; column < 9; column++) {
                addSlot(new Slot(playerInv, column + row * 9 + 9, 8 + column * 18, 125 + row * 18));
            }
        }
        //创建工具栏
        for (int col = 0; col < 9; ++col) {
            addSlot(new Slot(playerInv, col, 8 + col * 18, 183));
        }
        //创建纳米工具槽
        addSlot(new SlotItemHandler(blockTile.getInventory(), 0, 80, 91) {
            @Override
            public void onSlotChange(@Nonnull ItemStack oldStackIn, @Nonnull ItemStack newStackIn) {
                if (newStackIn.getItem() instanceof NanoTool) {
                    inventorySlots.clear();
                    loadSlot();
                }
                ;
            }

            @Override
            public boolean isItemValid(@Nonnull ItemStack stack) {
                return stack.getItem() instanceof NanoTool || stack.getItem() instanceof NanoRobot;
            }
        });
        //创建纳米工具内置槽位
        ItemStack stack = blockTile.getInventory().getStackInSlot(0);
        if (isNanoToolIn()) {
            IInventory inventory = ((NanoTool) stack.getItem()).getInventory(stack);
            addSlot(new MakerSlot(inventory, 0, 26, 43));
            addSlot(new MakerSlot(inventory, 1, 59, 15));
            addSlot(new MakerSlot(inventory, 2, 101, 15));
            addSlot(new MakerSlot(inventory, 3, 134, 43));
        } else {
            IItemHandler handler = blockTile.getInventory();
            addSlot(new EffectSlot(handler, 1, 26, 43));
            addSlot(new EffectSlot(handler, 2, 59, 15));
            addSlot(new EffectSlot(handler, 3, 101, 15));
            addSlot(new EffectSlot(handler, 4, 134, 43));
        }
    }

    private static class EffectSlot extends SlotItemHandler {
        public EffectSlot(IItemHandler itemHandler, int index, int xPosition, int yPosition) {
            super(itemHandler, index, xPosition, yPosition);
        }

        @Override
        public boolean isItemValid(@Nonnull ItemStack stack) {
            return stack.getItem() instanceof EffectStorageItem;
        }
    }

    private static class MakerSlot extends Slot {
        public MakerSlot(IInventory inventory, int index, int xPosition, int yPosition) {
            super(inventory, index, xPosition, yPosition);
        }

        @Override
        public boolean isItemValid(@Nonnull ItemStack stack) {
            return stack.getItem() instanceof ShieldMakerBase;
        }
    }

    //在gui内shift点击物品时的逻辑
    @Nonnull
    @Override
    public ItemStack transferStackInSlot(@Nonnull PlayerEntity playerIn, int slotIn) {
        ItemStack stack;
        Slot slot = inventorySlots.get(slotIn);

        if (slot == null || !slot.getHasStack()) {
            return ItemStack.EMPTY;
        }

        ItemStack itemStack = slot.getStack();
        stack = itemStack.copy();
        int invStart = 0;
        int invEnd = invStart + 27;
        int shortEnd = invEnd + 9;
        int guiEnd = shortEnd + 4;

        if (slotIn < shortEnd) {
            if (!mergeItemStack(itemStack, shortEnd, guiEnd, false)) {
                return ItemStack.EMPTY;
            }
        } else if (!mergeItemStack(itemStack, invEnd, shortEnd, false) && !mergeItemStack(itemStack, invStart, invEnd, false)) {
            return ItemStack.EMPTY;
        }

        if (itemStack.isEmpty()) {
            slot.putStack(ItemStack.EMPTY);
        } else {
            slot.onSlotChanged();
        }

        if (itemStack.getCount() == stack.getCount()) {
            return ItemStack.EMPTY;
        }

        slot.onTake(playerIn, itemStack);

        return stack;
    }

    @Override
    public boolean canInteractWith(@Nonnull PlayerEntity playerIn) {
        return isWithinUsableDistance(callable, playerIn, BlockList.NANO_ROBOT_PROGRAMMER.get());
    }

    public float getEnergyScaled() {
        int i = blockTile.getEnergy().getMaxEnergyStored();
        int j = blockTile.getEnergy().getEnergyStored();
        return i == 0 || j == 0 ? 0 : (float)j / i;
    }

    public int getEnergy() {
        return blockTile.getEnergy().getEnergyStored();
    }

    public IItemHandler getInv() {
        return blockTile.getInventory();
    }

    public boolean isNanoToolIn() {
        return blockTile.getInventory().getStackInSlot(0).getItem() instanceof NanoTool;
    }

    public BlockPos getPos() {
        return blockTile.getPos();
    }
}
